//
//  HTTPRequestManager.m
//  ZhaoQiPei
//
//  Created by 找汽配ios开发 on 15/11/28.
//  Copyright © 2015年 祥运. All rights reserved.
//

#import "HTTPRequest.h"
#import "HTTPRequestManager.h"
#import "UserCenter.h"
#import "MBProgressHUD.h"
#import "AFNetworking.h"

@interface HTTPRequest ()

@property (nonatomic, strong) AFHTTPSessionManager * httpSessionManager;

@end

@implementation HTTPRequest

+ (instancetype)request {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (self) {
        AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
        manager.requestSerializer.timeoutInterval = 20;
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/plain", @"text/javascript", @"application/javascript", nil];
//        _httpSessionManager.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
        // 2.设置证书模式
//        NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];
//        NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
//        manager.securityPolicy.pinnedCertificates = [NSSet setWithObject:cerData];
        // 客户端是否信任非法证书
        manager.securityPolicy.allowInvalidCertificates = YES;
        // 是否在证书域字段中验证域名
        [manager.securityPolicy setValidatesDomainName:NO];
        self.httpSessionManager = manager;
    }
    return self;
}

- (void)logWithTask:(NSURLSessionDataTask *)task responseObject:(id)responseObject {
//#ifdef DEBUG
    NSLog(@"\n<--\n%@\n%@\n%@\n-->\n", task.currentRequest.URL, task.taskDescription, responseObject);
//#endif
}

- (void)logWithTask:(NSURLSessionDataTask *)task error:(NSError *)error {
//#ifdef DEBUG
    NSLog(@"\n<--\n%@\n%@\n%@\n-->\n", task.currentRequest.URL, task.taskDescription, error);
//#endif
}

#pragma mark - HTTPRequest



#pragma mark - Action

- (void)GET:(NSString *)URLString parameters:(id)parameters {
    __block MBProgressHUD * hud = nil;
    // 执行网络请求
    self.task = [self.httpSessionManager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        [self logWithTask:task responseObject:responseObject];
        [self requestSuccessActionWithResponseObject:responseObject invalid:^{
            // 尝试重新登录
            [self reloginWithSuccess:^{
                // 重新执行网络请求
                self.task = [self.httpSessionManager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                    if (self.progress) {
                        [HTTPRequestManager hideProgressHUD:hud];
                    }
                    [self logWithTask:task responseObject:responseObject];
                    [self requestSuccessActionWithResponseObject:responseObject invalid:^{
                        // 放弃重新登录
                        HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
                        if (self.invalid) {
                            self.invalid();
                        }
                        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidInvalid)]) {
                            [manager.delegate httpRequestManagerDidInvalid];
                        }
                    }];
                } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                    if (self.progress) {
                        [HTTPRequestManager hideProgressHUD:hud];
                    }
                    [self logWithTask:task error:error];
                    [self requestFailureActionWithError:error];
                }];
                if (self.progress) {
                    hud = [HTTPRequestManager showProgressHUD];
                    [hud.button addTarget:self action:@selector(cancelButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
                }
            }];
        }];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        [self logWithTask:task error:error];
        [self requestFailureActionWithError:error];
    }];
    if (self.progress) {
        hud = [HTTPRequestManager showProgressHUD];
        [hud.button addTarget:self action:@selector(cancelButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    }
}

- (void)POST:(NSString *)URLString parameters:(id)parameters {
    __block MBProgressHUD * hud = nil;
    self.task = [self.httpSessionManager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        [self logWithTask:task responseObject:responseObject];
        [self requestSuccessActionWithResponseObject:responseObject invalid:^{
            // 尝试重新登录
            [self reloginWithSuccess:^{
                // 重新执行网络请求
                self.task = [self.httpSessionManager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                    if (self.progress) {
                        [HTTPRequestManager hideProgressHUD:hud];
                    }
                    [self logWithTask:task responseObject:responseObject];
                    [self requestSuccessActionWithResponseObject:responseObject invalid:^{
                        // 放弃重新登录
                        HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
                        if (self.invalid) {
                            self.invalid();
                        }
                        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidInvalid)]) {
                            [manager.delegate httpRequestManagerDidInvalid];
                        }
                    }];
                } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                    if (self.progress) {
                        [HTTPRequestManager hideProgressHUD:hud];
                    }
                    [self logWithTask:task error:error];
                    [self requestFailureActionWithError:error];
                }];
                if (self.progress) {
                    hud = [HTTPRequestManager showProgressHUD];
                    [hud.button addTarget:self action:@selector(cancelButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
                }
            }];
        }];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        [self logWithTask:task error:error];
        [self requestFailureActionWithError:error];
    }];
    if (self.progress) {
        hud = [HTTPRequestManager showProgressHUD];
        [hud.button addTarget:self action:@selector(cancelButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    }
}

- (void)dataGET:(NSString *)URLString parameters:(id)parameters {
    __block MBProgressHUD * hud = nil;
    self.task = [self.httpSessionManager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        if (self.completion) {
            self.completion(YES);
        }
//        [self logWithTask:task responseObject:responseObject];
        if (self.success) {
            self.success(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (self.progress) {
            [HTTPRequestManager hideProgressHUD:hud];
        }
        if (self.completion) {
            self.completion(NO);
        }
//        [self logWithTask:task error:error];
        [self requestFailureActionWithError:error];
    }];
    if (self.progress) {
        hud = [HTTPRequestManager showProgressHUD];
        [hud.button addTarget:self action:@selector(cancelButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    }
}

- (NSURLSessionUploadTask *)uploadWithRequest:(NSURLRequest *)request data:(NSData *)data progress:(void(^)(NSProgress * uploadProgress))progress {
    return [self.httpSessionManager uploadTaskWithRequest:request fromData:data progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) {
            progress(uploadProgress);
        }
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
        if (error) {
            [self logWithTask:nil error:error];
            [self requestFailureActionWithError:error];
        }
        else {
            [self logWithTask:nil responseObject:responseObject];
            [self requestSuccessActionWithResponseObject:responseObject invalid:^{
                // 放弃重新登录
                HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
                if (self.invalid) {
                    self.invalid();
                }
                else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidInvalid)]) {
                    [manager.delegate httpRequestManagerDidInvalid];
                }
            }];
        }
    }];
}

- (void)requestSuccessActionWithResponseObject:(id)responseObject invalid:(void(^)())invalid {
    HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
    if ([responseObject[@"message"][@"type"] isEqualToString:@"success"]) {
        if (self.completion) {
            self.completion(YES);
        }
        if (self.success) {
            self.success(responseObject);
        }
    }
    else if ([responseObject[@"message"][@"type"] isEqualToString:@"warn"]) {
        NSString * content = nil;
        if (responseObject[@"message"][@"content"] && responseObject[@"message"][@"content"] != [NSNull null]) {
            content = responseObject[@"message"][@"content"];
        }
        
        if (self.completion) {
            self.completion(NO);
        }
        if (self.warn) {
            self.warn(content);
        }
        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidRequestWarnWithContent:)]) {
            [manager.delegate httpRequestManagerDidRequestWarnWithContent:content];
        }
    }
    else if ([responseObject[@"message"][@"type"] isEqualToString:@"error"]) {
        NSInteger errorCode = 0;
        if (responseObject[@"message"][@"errCode"] && responseObject[@"message"][@"errCode"] != [NSNull null]) {
            errorCode = [responseObject[@"message"][@"errCode"] integerValue];
        }
        NSString * content = nil;
        if (responseObject[@"message"][@"content"] && responseObject[@"message"][@"content"] != [NSNull null]) {
            content = responseObject[@"message"][@"content"];
        }
        
        if ([content isEqualToString:@"session.invaild"]) {
            if (invalid) {
                invalid();
            }
        }
        else if (errorCode != 0) {
            if (self.completion) {
                self.completion(NO);
            }
            if (self.error) {
                self.error(errorCode, content);
            }
            else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidRequestErrorWithErrorCode:content:)]) {
                [manager.delegate httpRequestManagerDidRequestErrorWithErrorCode:errorCode content:content];
            }
        }
        else {
            if (self.completion) {
                self.completion(NO);
            }
            if (self.error) {
                self.error(ErrorCodeNone, content);
            }
            else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidRequestErrorWithErrorCode:content:)]) {
                [manager.delegate httpRequestManagerDidRequestErrorWithErrorCode:ErrorCodeNone content:content];
            }
        }
    }
}

- (void)requestFailureActionWithError:(NSError *)error {
    HTTPRequestManager * manager = [HTTPRequestManager sharedInstance];
    if (error.code == -999) {
        if (self.completion) {
            self.completion(NO);
        }
        if (self.cancel) {
            self.cancel();
        }
        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidCancel)]) {
            [manager.delegate httpRequestManagerDidCancel];
        }
    }
    else if (error.code == -1001) {
        if (self.completion) {
            self.completion(NO);
        }
        if (self.timeout) {
            self.timeout();
        }
        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidTimeOut)]) {
            [manager.delegate httpRequestManagerDidTimeOut];
        }
    }
    else if (error.code == -1009) {
        if (self.completion) {
            self.completion(NO);
        }
        if (self.offline) {
            self.offline();
        }
        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidOffline)]) {
            [manager.delegate httpRequestManagerDidOffline];
        }
    }
    else {
        if (self.completion) {
            self.completion(NO);
        }
        if (self.failure) {
            self.failure(error);
        }
        else if (manager.delegate && [manager.delegate respondsToSelector:@selector(httpRequestManagerDidRequestFailureWithError:)]) {
            [manager.delegate httpRequestManagerDidRequestFailureWithError:error];
        }
    }
}

#pragma mark - Button Action

- (void)cancelButtonTouchUpInside {
    [self.task cancel];
}

#pragma mark - Extension

/** 重新登录 */
- (void)reloginWithSuccess:(void(^)())success {
    
}

@end
